package com.blog.cloud.auth.controller;

import jakarta.validation.Valid;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

// 所有Restful API的处理方法参考： https://docs.spring.io/spring-framework/reference/web/webflux/controller/ann-methods.html
@RestController
@RequestMapping("/auth")
public class AuthController {

    // 从请求中地址中的路径参数中获取 id 并返回 Person 对象，例如 /auth/123
    @GetMapping("/{id}")
    public Person getPerson(@PathVariable Long id) {
        // ...
        return Person.builder()
                .id(id)
                .name("John Doe")
                .build();
    }

    // 从请求体中获取 Person 对象，@RequestBody 注解，通过 HttpMessageReader 将请求体读取并反序列化为对象。
    @PostMapping
    public void add(@RequestBody Person person) {
        // ...
    }

    // 与 Spring MVC 不同，在 WebFlux 中，@RequestBody 方法参数支持反应式类型和完全无阻塞的读取和（客户端到服务器）流。
    // 您可以将 @RequestBody 与 jakarta.validation.Valid 或 Spring 的 @Validated 注解结合使用，从而应用标准 Bean 验证
    @PostMapping("/persons")
    public void handle(@Valid @RequestBody Mono<Person> person) {
        // ...
    }

    // {name} 匹配一个路径段，并将其捕获为一个名为 name 的变量
    // 更多的匹配模式请参考 Spring 的 PathPatterns 类 https://docs.spring.io/spring-framework/reference/web/webflux/controller/ann-requestmapping.html
    @GetMapping("/owners/{ownerId}/pets/{petId}")
    public Person findPet(@PathVariable Long ownerId, @PathVariable Long petId) {
        // ...
        return Person.builder()
                .id(id)
                .name("John Doe")
                .build();
    }

    // 从请求地址的查询字符串中获取指定名称的参数，例如 /auth?petId=123
    @GetMapping
    public Person setupForm(@RequestParam("petId") Long petId) {
        return Person.builder()
                .id(petId)
                .name("John Doe")
                .build();
    }


    // 从请求的请求头中获取指定名称的参数，例如 Accept-Encoding: gzip, deflate, br
    @GetMapping("/demo")
    public void handle(
            @RequestHeader("Accept-Encoding") String encoding,
            @RequestHeader("Keep-Alive") long keepAlive) {
        //...
    }

    // 从请求的 Cookie 中获取指定名称的参数，例如 JSESSIONID=1234567890
    @GetMapping("/demo")
    public void handle(@CookieValue("JSESSIONID") String cookie) {
        //...
    }


    @Getter
    @Setter
    @Builder
    public static class Person {
        private Long id;
        private String name;
        // getters and setters
    }
}
